from Crypto.Util import randpool
from threading import local

def gen_nonce(size=20):
    return RandomPool.get_bytes(20)

def gen_nonce_str(size=40):
    bytes = RandomPool.get_bytes(size//2)
    s = ''.join('%.2x' % ord(byte) for byte in bytes)
    return s

class RandomPool(object):
    _local = local()

    @classmethod
    def get(klass):
        if not hasattr(klass._local, 'pool'):
            klass._local = randpool.RandomPool()
        return klass._local

    @classmethod
    def hash_bytes(klass, value):
        from hashlib import sha256
        return sha256(value).digest()

    @classmethod
    def hash_string(klass, value):
        from hashlib import sha256
        return sha256(value).hexdigest()

    @classmethod
    def get_bytes(klass, num, event='aaa'):
        pool = klass.get()
        pool.stir()
        pool.add_event(klass.hash_bytes(event))
        pool.stir()
        result = pool.get_bytes(num)
        pool.stir()
        pool.add_event(klass.hash_bytes(event))
        pool.stir()
        return result

    @classmethod
    def get_string(klass, num, event='aaa'):
        from hashlib import sha256
        bytes = klass.get_bytes(num // 2)
        return klass.hash_string(bytes)
        
